using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using ShopPowerTemplate.Entities;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace ShopPowerTemplate.WcfService
{
    public partial class WebService : WebServiceBase, IWebService
    {
        public Customer RegisterUserIfNecessary(string accessCode)
        {
            ShopPowerTemplate.Services.IAuthenticationService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IAuthenticationService>();

            var t = service.AddAuthenticationEntityFromLiveConnect(accessCode);
            t.Wait();

            return t.Result;
        }

        public Product FindProduct(int id)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            return service.Find(id);
        }

        public ProductDetail FindProductDetail(int id)
        {
            ShopPowerTemplate.Services.IProductDetailService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductDetailService>();
            return service.Find(id);
        }

        public List<Category> FindAllCategory()
        {
            ShopPowerTemplate.Services.ICategoryService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.ICategoryService>();
            return service.FindAll();
        }

        public Review AddReview(Review review)
        {
            ShopPowerTemplate.Services.IReviewService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IReviewService>();
            service.Add(review);

            return review;
        }

        public List<Subcategory> CategoryGetSubcategoriesFor(Category category)
        {
            ShopPowerTemplate.Services.ICategoryService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.ICategoryService>();
            category = service.Find(category.Id);

            return category.Subcategories.ToList();
        }

        public List<Product> SearchProduct(string searchValue)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            return service.Search(searchValue);
        }

        public List<Option> OptionTypeGetOptionsFor(OptionType optionType)
        {
            ShopPowerTemplate.Services.IOptionTypeService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IOptionTypeService>();
            optionType = service.Find(optionType.Id);

            return optionType.Options.ToList();
        }

        public List<Review> ProductGetReviewsFor(Product product)
        {
            ShopPowerTemplate.Services.IReviewService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IReviewService>();
            return service.Search(r => r.Product.Id == product.Id).ToList();
        }



        // Custom code here
        public List<Product> SearchProductCustomByRating(Category cat, Subcategory sub)
        { 
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            Func<Product, bool> searchCriteria = p => p.Subcategory.Category.Id == cat.Id && (sub == null || (p.Subcategory.Id == sub.Id));

            return service.SearchCustomByRating(searchCriteria);
        }

        public List<Product> SearchProductCustomByName(Category cat, Subcategory sub)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            Func<Product, bool> searchCriteria = p => p.Subcategory.Category.Id == cat.Id && (sub == null || (p.Subcategory.Id == sub.Id));

            return service.SearchCustomByName(searchCriteria);
        }

        public List<Product> SearchProductCustomByPrice(Category cat, Subcategory sub)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            Func<Product, bool> searchCriteria = p => p.Subcategory.Category.Id == cat.Id && (sub == null || (p.Subcategory.Id == sub.Id));

            return service.SearchCustomByPrice(searchCriteria);
        }

        public List<Product> SearchProductCustomByProminentAndName(Category cat, Subcategory sub)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            Func<Product, bool> searchCriteria = p => p.Subcategory.Category.Id == cat.Id && (sub == null || (p.Subcategory.Id == sub.Id));

            return service.SearchCustomByProminentAndName(searchCriteria);
        }

        public Image GetProductFirstImage(int productId)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            return service.GetFirstProductImage(productId);
        }

        public IEnumerable<Image> GetProductAllImage(int productId)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            return service.GetAllProductImage(productId);
        }

        public IEnumerable<OptionType> GetOptionTypes(int productId)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            return service.GetOptionTypes(productId);
        }

        public decimal GetShippingCost(decimal weight)
        {
            ShopPowerTemplate.Services.IShippingCostService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IShippingCostService>();
            return service.GetShippingCost(weight);
        }

        public IEnumerable<Product> GetProminentProducts()
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            return service.GetProminentProducts();
        }

        public bool StockAvailable(Product product, IEnumerable<Option> selectectOptions)
        {
            ShopPowerTemplate.Services.IProductService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductService>();
            return service.StockAvailable(product, selectectOptions);
        }

        public ProductDetail GetProductDetail(Product product, ICollection<Option> selectectOptions)
        {
            ShopPowerTemplate.Services.IProductDetailService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductDetailService>();
            return service.GetProductDetail(product, selectectOptions);
        }


        public ICollection<Option> GetProductDetailOptions(ProductDetail productDetail)
        {
            ShopPowerTemplate.Services.IProductDetailService service = IoC.IoCFactory.Resolve<ShopPowerTemplate.Services.IProductDetailService>();
            productDetail = service.Find(productDetail.Id);

            return productDetail.Option;
        }
    }
}

